package com.kins.so.test.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kins.executer.constants.Constant;
import com.kins.executer.constants.DataConstant;
import com.kins.executer.entitys.SOFlowRectsEntity;
import com.kins.so.choreographyflow.entity.SoTestLog;
import com.kins.so.common.rulebasebean.CfgSOExecuteParam;
import com.kins.so.openai.model.ExeFlowParams;
import com.kins.so.somanage.entity.SoManage;
import com.kins.so.somanage.mapper.SoManageMapper;
import com.kins.so.somanage.service.impl.SoManageService;
import com.kins.so.test.enetity.ResponseVO;
import com.kins.so.test.enetity.SoFlowExeResultLog;
import com.kins.so.test.mapper.SoFlowExeResultLogMapper;
import com.kins.so.test.service.SOTestService;
import com.kins.so.test.vo.SoFlowExeResultLogVo;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ImportResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.lang.reflect.ParameterizedType;
import java.sql.SQLOutput;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * @Description:
 * @Author: 申科
 * @Date:2025/11/8 11:32
 */

@Slf4j
@Service
public class SOTestServiceImpl implements SOTestService {
    @Autowired
    private SOVersioninfoService soVersioninfoService;
    @Autowired
    private SoManageMapper soManageMapper;

    @Autowired
    private SOFlowRectsService soFlowRectsService; //SOFlow业务层
    @Autowired
    private  ProdAppMockDao mockDao;
    @Autowired
    private LogFlowService logFlowService;

    @Resource
    private SoFlowExeResultLogMapper soFlowExeResultLogMapper;
    @Value("${mock.url}")
    private String url;

    @Value("${edoc.file.image.path:/home/edoc/file/images")
    private String imageBasePath;

    @Value("${execute.fongi.url}")
    private String executerUrl;

    @Value("${execute.fongi.isUrl}")
    private boolean isUrl;

    @Autowired
    private SoManageService soManageService;

    @Autowired
    private ExecuteService executeService;

    @Autowired
    private DroolsExcuteDrulUtils dedu;

    @Autowired
    private SoLogService ruleLogService;

    @Autowired
    private SoInterfaceParamMappingService soInterfaceParamMappingService;

    public static ExecutorService executorService = Executors.newFixedThreadPool(10);

    /**
     * 服务编排测试
     */
    @SneakyThrows
    @Override
    public Map<String, Object> testRule(CfgSOExecuteParam testInfo){
        //根据ID获取服务编排配置的路径访问执行器
        SoManage soManage = soManageService.get(testInfo.getSoId());//服务ID
        if(soManage==null){
            throw new BizException("无法获取编排基本信息");

        }
        String oriRequest = JSON.toJSONString(testInfo.getRequestParams());
        //获取执行参数
        Map<String, Object> inputJson = testInfo.getInputJson();
        //测试调用标识
        inputJson.put("version", Constant.DEFALT_VERSION_NUM);
        inputJson.put(DataConstant.INPUTDATA_ORGCODE,testInfo.getOrgCode());
        String result = "";
        if(isUrl){
            //并排执行器地址及服务编排访问路径
            String url = executerUrl + (soManage.getPath() == null ? "": soManage.getPath());
            //调用远程的执行器进行测试
            result = RestTemplateUtils.post(url, JSON.toJSONString(inputJson));

        }else{
            Map<String,Object> testParamMap = new HashMap<>();
            testParamMap.put(DataConstant.INPUTDATA_VERSION, testInfo.getVersion());
            testParamMap.put(DataConstant.INPUTDATA_BUSINESSINPUT,inputJson);
            String url = soManage.getPath();
            result = executeService.execute(testParamMap, soManageService.getMethod(), url);

        }
        Map<String, Object> resultMap = JSON.parseObject(result, Map.class);

        Object runFlowId = testInfo.getInputJson().get(Constant.RUNFLOW_ID);//入参
        SoFlowExeResultLog soFlowExeResultLog = new SoFlowExeResultLog();
        soFlowExeResultLog.setId(TjmasDisKeyGenerator.generateSnowKey().toString());
        soFlowExeResultLog.setAnalysisPath(testInfo.getPath());
        if(runFlowId != null){
            soFlowExeResultLog.setRunFlowId(runFlowId.toString());
        }
        soFlowExeResultLog.setRequestInfo(oriRequest);
        soFlowExeResultLog.setCustomerName(MapUtils.getString(testInfo.getInputJson(),"rg_customerName"));//入参
        soFlowExeResultLog.setCustomerCertNo(MapUtils.getString(testInfo.getInputJson(), "rg_customerCertNo"));//入参
        soFlowExeResultLog.setCustomerCertType(MapUtils.getString(testInfo.getInputJson(),"rg_customerCertType"));//入参
        soFlowExeResultLog.setResult(result);
        soFlowExeResultLog.setCreateTime(new Date());

        Map<String, Object> condMap = new HashMap<>();
        condMap.put("runFlowId", soFlowExeResultLog.getRunFlowId());
        condMap.put("customerCertNo", soFlowExeResultLog.getCustomerCertNo());
        condMap.put("analysisPath",soFlowExeResultLog.getAnalysisPath());
        soFlowExeResultLogMapper.deleteByMap(condMap);

        soFlowExeResultLog.setAnalysisType(testInfo.getAnalysisType());//分析类型
        soFlowExeResultLogMapper.insert(soFlowExeResultLog);
        return resultMap;

    }

    @Override
    public ResponseVO exeFlow(ExeFlowParams exeFlowParams){
        ResponseVO responseVO = new ResponseVO();
        if(StringUtil.isEmpty(exeFlowParams.getPath())){
            responseVO.setStatus(ResponseVO.ERROR);
            responseVO.setDescription("访问路径不能为空！");
            return responseVO;
        }
        SoManage tempSoManage = new SoManage();
        tempSoManage.setPath(exeFlowParams.getPath());//访问路径
        List<SoManage> tempList = this.soManageMapper.findListByPath(tempSoManage);
        if(tempList == null || tempList.size() <=0){
            responseVO.setStatus(ResponseVO.ERROR);
            responseVO.setDescription("未找到执行的流程！");
            return responseVO;
        }
        CfgSOExecuteParam paramData = new CfgSOExecuteParam();//服务编排执行和测试的入参
        paramData.setSoId(tempList.get(0).getId());//服务ID
        paramData.serVersion(tempList.get().getVersion());//规则模型版本
        paramData.sertInputJson(exeFlowParams.getInputJson());
        paramData.setPath(exeFlowParams.getPath());
        paramData.setRequestParams(exeFlowParams);
        String runFlowId = exeFlowParams.getBusinessSeqNo();//业务流水好
        paramData.getInputJson().put(dataConstant.INPUTDATA_BUSINESSNO,exeFlowParams.getBusinessSeqNo());//业务流水号
        if(StringUtils.isEmpty(runFlowId)){
            runFlowId = CstsqlIdGen.uuid();
        }
        paramData.getInputJson().put(Constant.RUNFLOW_ID,runFlowId);//入参
        paramData.setOrgCode(exeFlowParams.getOrgCode());//机构和
        paramData.setAnalysisType(exeFlowParams.getAnalysisType());//分析类型
        //执行服务编排
        executorService.execute(() ->{
            testRule(paramData);//服务编排的测试
        });
        HashMap<String,Object> map = new HashMap<>();
        map.put(Constant.RUNFLOW_ID.runFlowId);
        responseVO.setData(map);
        responseVO.setStatus(ResponseVO.OK);
        return responseVO;
    }

    @Override
    public ResponseVO getFlowResult(String runFlowId){
        ResponseVO responseVO = new ResponseVO();
        SoFlowExeResultLog soFlowExeResultLog soFlowExeResultLogMapper.getByRunFlowId(runFlowId);
        if(soFlowExeResultLog == null){
            responseVO.setStatus(210);
            responseVO.setDescription("流程还在执行中！");

        }else {
            responseVO.setStatus(ResponseVO.OK);
            JSONObject result = JSON.ParaseObject(soFlowExeResultLog.getResult());
            responseVO.setData(result);
        }
        return responseVO;
    }

    /**
     *
     */
    @Override
    public ResponseVO getFlowParaseResult(Map<String, Object> paramMap){
        List<String> certNos = Arrays.asList(MapUtil.getStr(paramMap, "certNos", "").split("."));
        RespnseVO responseVO = new ResponseVO();
        List<SoFlowExeResultLog> soFlowExeResultLogList = soFlowExeResultLogMapper.getByMap(paramMap);
        if(soFlowExeResultLogList == null || soFlowExeResultLogList.isEmpty()){
            responseVO.setStatus(ResponseVO.ERROR);
            responseVO.setDescription("未找到相关分析结果数据");
        }else{
            responseVO.setStatus(ResponseVO.OK);
            List<SoFlowExeResultLogVo> resultList = new ArrayList<>();
            soFlowExeResultLogList.forEach(soFlowExeResultLog -> {
                //过滤数据
                JSONObject result = JSON.parseObject(soFlowExeResultLog.getResult());
                JSONObject data = result.getJSONObject("data");
                if(data == null){
                    return;
                }
                JSONObject newData = new JSONObject();
                data.forEach((key, value)->{
                    if("retCode".equals(key) || "retMsg".equals(key)){
                        newData.put(key,value);
                        return ;
                    }
                    Map<String,Object> resultMap = JSON.parseObject(value.toString(),Map.class);
                    //处理
                    if(resultMap !=null){
                        Object answerObj = resultMap.get("answer");
                        if(answerObj == null){
                            log.warn("key={}的answerzi字段为空",key);
                            return ;
                        }
                        String answerStr = answerObj.toString();
                        String cleanedAnswer = answerStr.replaceAll("//[ID:\\d+\\]","").replaceAll("\\s+","").trim();
                        try{
                            newData.put(key,cleanedAnswer);

                        }catch (Exception e){
                            log.error("结果解析异常"+value, e.getMessage());
                        }
                    }
                });
                result.put("data",newData);
                if(!StringUtils.isEmpty(soFlowExeResultLog.getAnalysisPath())){
                    resultList.add(buildVo(soFlowExeResultLog, result));
                }else{
                    log.warn("so_flow_exeresult_log表里的{}记录字段analysis_path为空",soFlowExeResultLog.getId());

                }
            });
            responseVO.setData(resultList);
        }
        return responseVO;
    }

    private SoFlowExeResultLogVo buildVo(SoFlowExeResultLog log, JSONObject result){
        SoFlowExeResultLogVo vo = new SoFlowExeResultLogVo();
        vo.setId(log.getId());
        vo.setRunFlowId(log.getRunFlowId());
        vo.setAnalysisPath(log.getAnalysisPath());
        vo.setCustomerCertNo(log.getCustomerCertNo());
        vo.setReturnCode(result.getString("returnCode"));
        vo.setResult(result.getJSONObject("data"));
        return vo;
    }

    @Override
    public ResponseVO asnycRunFlow(CfgSOExecuteparam paraData) throws Exception{
        RespnseVO resp = enw ResonseVO();
        String runFlowId = CstsqlIdGen.uuid();
        paramData.getInputJson().put(Constant.RUNFLOW_ID,runFlowId);//入参
        //执行服务编排
        executorService.execute(() ->{
            testRule(paraData);//服务编排的测试

        });
        HashMap<String,Object> map = new HashMap<>();
        map.put(Constant.RUNFLOW_ID.runFlowId);
        resp.setData(map);
        resp.setStatus(ResponseVO.OK);
        return resp;
    }

    /**
     * 服务编排的测试
     *
     */
    @Override //继续drl测试
    public Map<String, Object> continueSoTest(String logid) throws Exception(){
        DroolsExcuteDrulUtils dedu = new DroolsExcuteDrulUtils();//执行drools脚本的工具内
        Map<String, Objcet> insertMap = new HashMap<>();

        //服务编排节点及子节点信息
        Map<String, SOFlowRectsEntity> rectsMap = new HashMap<>();
        SoManage soManage = soManageMapper.findByLogId(logId);
        if(soManage == null){
            throw new Exception("服务编排不存在");
        }
        if("1".equals(soManage.getMockFlag())){
            return MockUtils.getMockData(soManage.getApiName(),url);
        }

        //存测试日志
        SoTestLog soTestLog = new SoTestLog();
        soTestLog.setServiceCode(soManage.getApiName());
        soTestLog.setServiceId(soManage.getId());
        soTestLog.setServiceVersion(soManage.getVersion());
        soTestLog.setCreateDate(new Date());

        MappingParamVo rectVo = new MappingParamVo();
        //主服务编排默认插入
        rectVo.setServiceArrangeId(soManage.getId());
        rectVo.setServiceArrangeVersion(soManage.getVersion());
        rectVo.setInterfaceId(soManage.getId());
        rectVo.setInterfaceVersion(soManage.getVersion());
        rectVo.setApiName(soManage.getApiName());//存的是服务的英文名
        rectsMap.put(DataUtils.getRectsKeyStr(rectVo),null);

        String soId = soManage.getId();
        SOVersioninfoEntity condition = new SOVersioninfoEntity();
        condition.setSoId(jsoId);
        condition.setVersion(soManage.getVersion());
        List<SOVersioninfoEntity> list = this.soVersioninfoService.findList(condition);
        SOFlowRectsEntity soFlowRectsEntity = new SOFlowRectsEntity();
        soFlowRectsEntity.setSoId(soId);
        soFlowRectsEntity.setVersion(soManage.getVersion());
        List<SOFlowRectsEntity> rectslist = soFlowRectsService.findList(soFlowRectsEntity);
        String soContent= "";
        for(SOVersioninfoEntity entity:list){
            if(entity.getModelType() == null){
                soContent = entity.getSoContent();
            }
        }
        //节点排序
        Map<String,Integer> nodeSortMap = DataUtils.nodeSort(soContent, rectslist.size());
        List<SoLog> soLogList = ruleLogService.getByLogId(logId);
        //阻塞节点id
        String suspendNodeId = "";
        //输出参数集合
        LinkedHashMap<String,HashMap> resultParamMap = new LinkedHashMap<>();
        for (SoLog soLog : soLogList){
            HashMap<String, Object> map = new HashMap<>();
            HashMap resultParam = JSONObject.parseObject(soLog.getOutputJson(), HashMap.class);
            map.put(BaseParamEnum.OUT_PARAM.getType(),resultParam);

            resultParamMap.put(DataUtils.getJoinStr(Constant.SPLIT_STR,soLog.getNodeId(), soLog.getInterfaceId()),map);
            if(Constant.IS_SUSPEND.equals(soLog.getNodeType())){
                suspendNodeId = soLog.getNodeId();
            }
        }

        this.collectBpmn(soId, soManage.getVersion(), list, rectsMap);
        //查询变量映射及变量定义
        Map<String, Object> servceInfoMap = new HashMap<>();
        servceInfoMap.put(BaseParamEnum.SERVICE_ARRANGE_ID.getType(),soId);
        servceInfoMap.put(BaseParamEnum.SERVICE_ARRANGE_CODE.getType(),soManage.getApiName());
        servceInfoMap.put(BaseParamEnum.SERVICE_ARRANGE_VERSION.getType(), soManage.getVersion());
        //服务编排信息
        insertMap.put(Constant.SERVICE_ARRANGE_INFO,servceInfoMap);
        //节点信息
        insertMap.put(Constant.RECTS_MAP,rectsMap);
        //节点排序
        insertMap.put(Constant.NODE_SORE_MAP,nodeSortMap);
        //流程开关
        insertMap.put(Constant.PROCESS_SWITCH_KEY,Constant.PROCESS_SWITCH_KEY_1);
        insertMap.put(Constant.SUSPEND_NODE_KEY,suspendNodeId);
        insertMap.put(Constant.IS_RESUME_TEST_KEY,true);
        //todo从日志中找出当前流水的参数备份放到RESULT_PARAM
        insertMap.put(Constant.RESULT_PARAM,null);
        MappingParamVo vo = MappingParamVo.getData(insertMap);//映射VO
        LogFlow logFlow = new LogFlow();
        logFlow.setLogId(logId);
        logFlowService.deleteByCondition(logFlow);
        dedu.continueExecuteSoDebugContents(insertMap, list, soManage.getApiName(), null,logId);//存的是服务的英文名
        //处理结果数据
        //主服务编排的默认的节点ID
        vo.setNodeId(Constant.MAINFLOW_NODEID);
        vo.setInterfaceId(vo.getServiceArrangeId());
        vo.setInterfaceVersion(vo.getServiceArrangeVersion());
        //出餐数据
        Map<String, Object> reMap =
                (Map<String, Object>) ParamLogUtils.getLogMap(insertMap, ParamLogUtils.getLogInterfaceKey(vo), BaseParamEnum.OUT_PARAM.getType());
        reMap.remove(Constant.START_DATE_KEY);
        reMap.remove(Constant.END_DATE_KEY);
        soTestLog.setOutputParam(JSON.toJSONString(reMap));
        //流程ID
        soTestLog.setId(OtherParamUtils.getRunFlowId(insertMap));
        LogCacheUtils.setTestLog(soTestLog);
        return reMap;
    }
    /**
     * 将某个服务编排下的
     */
    private void collectBpmn(String soId, String version,
                             List<SOVersioninfoEntity> soVersioninfoEntities,//存放drools实体类
                            Map<String, SOFlowRectsEntity> rectsMap){
        SOFlowRectsEntity condition = new SOFlowRectsEntity();
        condition.setSoId(soId);
        condition.setVersion(version);
        List<SOFlowRectsEntity> list = soFlowRectsService.findList(condition);
        if(list !=null){
            for(SOFlowRectsEntity item : list){
                String rectType = item.getRectType();
                String apiName = "";
                String newInterfaceVersion = "";
                if(ServiceTypeEnum.ServiceChreography.getType().equals(rectType)){
                    String rectCode = item.getRectCode();
                    String rectVersion = item.getRectVersion();
                    SOVersioninfoEntity soVersioninfoEntity = new SOVersioninfoEntity();
                    soVersioninfoEntity.setSoId(rectCode);
                    soVersioninfoEntity.setVersion(rectVersion);
                    List<SOVersioninfoEntity> callVersionInfos = this.soVersioninfoService.findList(soVersioninfoEntity);
                    soVersioninfoEntities.addAll(callVersionInfos);
                    SoManage = soManageParam = soManageMapper.get(rectCode);
                    apiName = soManage.getApiName();
                    collectBpmn(rectCode,rectVersion,soVersioninfoEntities,rectsMap);
                }else if (ServiceTypeEnum.StartNode.getType().equals(rectType) ||
                        ServiceTypeEnum.EndNode.getType().equals(rectType)){
                    continue;
                }
                MappingParamVo vo = new MappingParamVo();
                vo.setServiceArrangeId(item.getSoId());
                vo.setServiceArrangeVersion(item.getVersion());
                vo.setInterfaceId(item.getRectCode());
                vo.setInterfaceVersion(item.getRectVersion());
                vo.setApiName(apiName);
                vo.setNewInterfaceVersion(newInterfaceVersion);
                vo.setNodeId(item.getNodeId());
                rectsMap.put(DataUtils.getRectsKeyStr(vo),item);
            }
        }
    }

    /**
     * 缓存服务下的节点的ID
     */

    private void cacheRectNodeIds(SoManage soManage, String key){
        String id = soManage.getid();
        SOFlowRectsEntity condition = new SOFlowRectsEntity();
        condition.setSoId(id);
        condition.setVersion(soManage.getVersion());
        List<SOFlowRectsEntity> result = this.soFlowRectsService.findList(condition);
        List<String> list = new ArrayList<>();
        Map<String, String> map = new HashMap<>();
        if(result != null && !result.isEmpty()){
            result.forEach(item -> {
                list.add(item.getNodeId());

                String rectType = item.getRectType();
                if(ServiceTypeEnum.ServiceChoreography.getType().equals(rectType)){
                    String nodeId = item.getNodeId();
                    String rectName = item.getRectName();
                    String rectCode= item.getRectCode();
                    map.put(rectName, nodeId + "_" +rectCode);
                }
            });
        }
        //缓存服务编排下各节点的ID
        AppCacheInfo.rectIds.put(key,list);
        //缓存子服务下各节点的ID
        AppCaacheInfo.sunServiceNodeIdAnadName.put(key,map);

    }

    public void analyticalVariables(List<ServiceInterfaceParamInfo> inputParams, Object inputJson, String type){
        if("List".equals(type)){
            //确保inputJson是List类型
            List<Object> inputList = (List<Object>) inputJson;

            //List类型时，先创建一个Map，存放List的元素
            Map<String, Object> obj = new HashMap<>();
            for(ServiceInterfaceParaminfo param : inputParams){
                if(param.getChildren( != null && !param.getChildren().isEmpty()){
                    //如果有子元素，递归处理
                    analyticalVariables(param.getChildren(),obj,"Map");
                }else{
                    //没有子元素，直接添加到当前对象
                    obj.put(param.getParamName(),convertValue(param));
                }
            }
            //将收集好的对象添加到数组中
            inputList.add(obj);
        }else{
            //确保inputJosn时是Map类型
            Map<String, Object> inputMap = (Map<String, Object>) inputJson;
            for(ServiceInterfaceParamInfo param : inputParams){
                String paramType = param.getParamType();
                if(paramType.contains("Arrays") || paramType.contains("List")){
                    if(paramType.contains("File")){
                        String[] fileName = param.getValue().split(";");
                        String file = "filel:";
                        for (String i : fileName){
                            file = file+FileUtil.file(imageBasePath,i).toString()+";";
                        }
                        inputMap.put(param.getParamName(),file);//变量英文名
                        System.out.println("inputParams: " + param.getValue());
                    }else{
                        List<Object> objectList = new ArrayList<>();
                        if(param.getChidren() != null && !param.getChildren().isEmpty()){
                            analyticalVariables(param.getChildren(),objectList,"List");
                        }
                        inputMap.put(param.getParamName(),objectList);
                    }
                }else if (param.getChildrent() != null && !param.getChildren().isEmpty()){
                    Map<String,Object> nestedMap = new HashMap<>();
                    inputMap.put(param.getParamName(),nestedMap);
                    analyticalVariables(param.getChildren(),nestedMap,"Map");
                }else{
                    inputMap.put(param.getParamName(),convertValue(param));//变量英文名
                }
            }
        }
    }

    private Object convertValue(ServiceInterfaceParamInfo param){
        if (param == null || param.getValue() == null){
            return "";
        }
        String paramType = param.getParamType();
        String value = param.getValue().trim();

        try{
            if(value.isEmpty()){
                return "";
            }
            //使用switch语句可能更清晰
            switch (paramType.toLowerCase()){
                case "double":
                case "java.lang.double":
                    return Double.parseDouble(value);

                case "float":
                case "java.lang.float":
                    return Float.parseFloat(value);
                case "short":
                case "java.lang.short":
                    return  Float.parseFloat(value);
                case "long":
                case "java.lang.long":
                    return Long.parseLong(value);


                case "boolean":
                case "java.lang.boolean":
                    if("1".equals(value) || "true".equalsIgnoreCase(value))
                        return true;
                    else if ("0".equals(value) || "false".equalsIgnoreCase(value))
                        return false;
                    else {
                        throw new IllegalAccessException("Invalid boolean value: " +value);
                    }
                default:
                    //对于不支持的类型，可以记录日志
                    System.out.println("未知的参数类型："+paramType + "，将使用字符串作为默认值");
                    return param.getValue();
            }
        }catch (NumberFormatException e){
            throw new IllegalArgumentException(
                    String.format("无法取值 '%s' 转换为 %s类型，",value,paramType,e);

        }
    }

}
